package com.weixiao.api;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.weixiao.handler.YyghException;
import com.weixiao.model.user.UserInfo;
import com.weixiao.result.JwtHelper;
import com.weixiao.result.Result;
import com.weixiao.result.ResultCodeEnum;
import com.weixiao.service.UserInfoService;
import com.weixiao.utils.ConstantPropertiesUtil;
import com.weixiao.utils.HttpClientUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * author 韩诚
 * date 2022/10/27
 */
@Api(tags = "微信登录管理")
@Controller
@RequestMapping("/api/ucenter/wx")
@Slf4j
public class WeixinApiController {

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 生成微信扫描二维码
     * 返回生成二维码所需参数
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "生成微信登录二维码")
    @GetMapping("getLoginParam")
    @ResponseBody
    public Result genQrConnect() throws Exception {
        //创建一个map集合
        Map<String, Object> map = new HashMap<>();
        //向map集合中添加生成二维码所需要的参数
        map.put("appid", ConstantPropertiesUtil.WX_OPEN_APP_ID);
        map.put("scope", "snsapi_login");
        map.put("redirect_uri", URLEncoder.encode(ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL, "UTF-8"));
        map.put("state", System.currentTimeMillis() + "");
        //将map返回到前端
        return Result.ok(map);
    }

    /**
     * 扫码后回调函数获取用户信息
     *
     * @param code
     * @return
     * @throws Exception
     */
    @RequestMapping("callback")
    public String callback(String code) throws Exception {
        //获取授权临时票据code
        System.out.println("微信授权服务器回调。。。。。。");
        System.out.println("code = " + code);

        //拿着code和微信id以及秘钥，请求微信固定地址，得到两个值access_token跟openid
        //使用code和appid以及appscrect换取access_token跟openid
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                //固定地址，后面是参数，使用字符串拼接，%s是占位符
                .append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=%s")//id
                .append("&secret=%s")//秘钥
                .append("&code=%s")//code
                .append("&grant_type=authorization_code");//授权类型

        //填补占位符
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                ConstantPropertiesUtil.WX_OPEN_APP_ID,
                ConstantPropertiesUtil.WX_OPEN_APP_SECRET,
                code);

        //使用httpclient请求这个地址
        String result = HttpClientUtils.get(accessTokenUrl);
        //使用工具类将得到的字符串转换成JSON格式，并取出其中的access_token跟openid
        JSONObject resultJson = JSONObject.parseObject(result);
        String accessToken = resultJson.getString("access_token");
        String openId = resultJson.getString("openid");

        //查询数据库中是否有此微信的扫描人信息
        //根据openid判断
        UserInfo userInfo = userInfoService.selectWxInfoOpenId(openId);
        //如果数据库中没有此信息，则加入数据
        if (ObjectUtil.isNotNull(userInfo)) {
            //拿着openid跟access_token请求微信地址，得到扫码人信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" + "?access_token=%s" + "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openId);
            String resultUserInfo = HttpClientUtils.get(userInfoUrl);

            //解析用户信息
            JSONObject resultUserInfoJson = JSONObject.parseObject(resultUserInfo);
            //用户昵称
            String nickname = resultUserInfoJson.getString("nickname");
            //用户头像
            String headimgurl = resultUserInfoJson.getString("headimgurl");

            //将用户信息添加到数据库
            userInfo = new UserInfo();
            userInfo.setOpenid(openId);
            userInfo.setNickName(nickname);
            userInfo.setStatus(1);
            userInfoService.save(userInfo);
        }


        //使用jkt生成token并返回到前端页面
        Map<String, Object> map = new HashMap<>();
        String name = userInfo.getName();
        if (StringUtils.isBlank(name)) {
            name = userInfo.getNickName();
        }
        if (StringUtils.isBlank(name)) {
            name = userInfo.getPhone();
        }
        map.put("name", name);
        //判断userInfo是否有手机号，如果手机号为空，返回openid，如果不为空，返回openid为空字符串
        //前端判断，如果openid不为空，需要绑定手机号，为空，不需要绑定
        if (StringUtils.isBlank(userInfo.getPhone())) {
            map.put("openid", userInfo.getOpenid());
        } else {
            map.put("openid", "");
        }
        //生成token
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("token", token);
        //跳转到前端页面，并将数据以参数方式携带  ConstantPropertiesUtil.YYGH_BASE_URL：localhost:3000 这是前端端口号地址
        return "redirect:" + ConstantPropertiesUtil.YYGH_BASE_URL + "/weixin/callback?token=" + map.get("token") + "&openid=" + map.get("openid") + "&name=" + URLEncoder.encode((String) map.get("name"));
    }
}